home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / drgnsmth.cpt / Dragonsmith 1.1 / Base files / Utilities / ResourceUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-10  |  4.8 KB  |  158 lines

  1. /*
  2.     ResourceUtils.c
  3.     
  4.     Created    21 Aug 1992    CopyResource
  5.     Modified    22 Aug 1992    Revised CopyResource and renamed it CopyResHandle
  6.                         Added SaveRes and PreserveRes
  7.             29 Aug 1992    Added overwrite parameter to CopyResHandle
  8.             10 Oct 1992    Made CopyResHandle smarter when replacing resources
  9.             
  10.     Copyright ⌐ 1992 by Paul M. Hoffman
  11.     Send comments or suggestions to paul.hoffman@um.cc.umich.edu
  12.     
  13.     This source code may be freely used, altered, and distributed in any way as long as:
  14.         1.    It is GIVEN away rather than sold (except as expressly permitted by the author)
  15.         2.    This statement and the above copyright notice are left intact.
  16.  
  17. */
  18.  
  19. #include    "ResourceUtils.h"
  20. #include    "HandleUtils.h"
  21.  
  22. OSErr SaveRes (Handle h)
  23. {
  24.     OSErr    err;
  25.     
  26.     if (h != NULL && *h != NULL) {
  27.         ChangedResource (h);
  28.         if ((err = ResError ()) == noErr) {
  29.             WriteResource (h);
  30.             err = ResError ();
  31.         }
  32.         return err;
  33.     } else
  34.         return nilHandleErr;
  35. }
  36.  
  37. OSErr CopyResHandle (Handle h, short destRF, Boolean overwrite)
  38. {
  39.     // Copy a resource to the open resource file specified by the destRF parameter
  40.     
  41.     // The handle specified by the parameter h must be a resource handle ╤ it must have been obtained with a call to
  42.     //    GetResource or any other resource-loading call.  It may be purged (i.e., an empty handle) ╤ if so, the resource
  43.     //    will be read into memory before any copying takes place.  An error will be returned if the resource couldn't be
  44.     //    read into memory.  Regardless of what happens, the state of h will not be affected in any way
  45.     
  46.     // The resource is copied using the same type, ID, and name.  All resource attributes (Purgeable, Locked, Protected,
  47.     //    etc.) will be preserved in the destination file's copy
  48.     
  49.     // If a resource of the same type and ID is already present in the destination file, then we'll either overwrite it with the block
  50.     //    referred to by h (if overwrite == TRUE), or return with no error
  51.     
  52.     // If the resource has been changed, the changes will be preserved whether ChangedResource has been called or not
  53.     
  54.     short    ID, attrs, sourceRF, saveRF;
  55.     ResType    type;
  56.     Str255    name;
  57.     OSErr    err;
  58.     Handle    newHndl = NULL, tempHndl = NULL;
  59.     char        hState;
  60.     
  61.     // Avoid thrashing memory with references to an invalid handle
  62.     if (h == NULL)
  63.         return resNotFound;
  64.     
  65.     // Make sure that we have a valid refNum
  66.     if (destRF == kInvalidRefNum)
  67.         return rfNumErr;
  68.     
  69.     // Make sure the resource does NOT belong to the destination file ╤ if it does, then we're done
  70.     if (HomeResFile (h) == destRF)
  71.         return noErr;
  72.         
  73.     // Make sure the resource is in memory
  74.     if (*h == NULL) {
  75.         LoadResource (h);
  76.         if (err = ResError ()) return err;
  77.     }
  78.         
  79.     // Remember which resource file was the current one
  80.     saveRF = CurResFile ();
  81.     if (saveRF != destRF)
  82.         UseResFile (destRF);
  83.  
  84.     // Find out what type, ID, name, and attributes the resource we're copying has
  85.     GetResInfo (h, &ID, &type, name);
  86.     if (err = ResError ()) goto END;
  87.     attrs = GetResAttrs (h);
  88.     if (err = ResError ()) goto END;
  89.     
  90.     // Don't let the resource be purged before we can copy it
  91.     hState = HGetState (h);
  92.     HNoPurge (h);
  93.         
  94.     // Check to see if there's already a resource of the same type and ID in the destination file
  95.     SetResLoad (FALSE);                    // Avoid actually reading the resource into memory
  96.     tempHndl = Get1Resource (type, ID);
  97.     SetResLoad (TRUE);                    // Without this, the system would crash and burn very soon!
  98.     if (tempHndl != NULL) {
  99.         // If the resource already exists then check to see if we should overwrite it
  100.         if (overwrite) {
  101.             LoadResource (tempHndl);                // Read the resource into memory
  102.             err = ResError ();
  103.             if (err == noErr) {
  104.                 err = CopyHandle (h, tempHndl);        // Overwrite it with the data in the parameter handle
  105.                 if (err == noErr) {
  106.                     SetResInfo (tempHndl, ID, name);
  107.                     err = ResError ();
  108.                 }
  109.                 if (err == noErr) {
  110.                     SetResAttrs (tempHndl, attrs & ~resChanged);
  111.                     err = SaveRes (tempHndl);        // Save the modified resource
  112.                 }
  113.             }
  114.             ReleaseResource (tempHndl);            // Free up the memory it was using
  115.             if (err == noErr)
  116.                 err = ResError ();
  117.         } else
  118.             err = addResFailed;
  119.         goto END;
  120.     }
  121.  
  122.     // Now make a copy of the resource and add it to the destination file with the correct attributes
  123.     newHndl = h;
  124.     if (err = HandToHand (&newHndl)) goto END;
  125.     HNoPurge (newHndl);
  126.     AddResource (newHndl, type, ID, name);
  127.     if (err = ResError ()) goto END;
  128.     SetResAttrs (newHndl, attrs);
  129.     if (err = ResError ()) {
  130.         RmveResource (newHndl);
  131.         goto END;
  132.     }
  133.     
  134.     // Save the resource to disk
  135.     ChangedResource (newHndl);
  136.     WriteResource (newHndl);
  137.  
  138.     // Make it a non-resource handle (another copy is safe and sound in the destination file, unless there was an error)
  139.     if ((err = ResError ()) == noErr)
  140.         DetachResource (newHndl);
  141.     else
  142.         RmveResource (newHndl);
  143.  
  144. END:
  145.  
  146.     if (newHndl != NULL)
  147.         DisposHandle (newHndl);
  148.  
  149.     // Preserve saved states
  150.     HSetState (h, hState);
  151.     if (saveRF != destRF)
  152.         UseResFile (saveRF);
  153.  
  154.     return err;
  155.     
  156. }
  157.  
  158.